﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.Text;

namespace AutoUnitTestEngine.Helpers
{
    public class DataCompareHelper
    {
        

        /// <summary>
        /// 比较行记录中的列内容，如果不相等，就以右边的内容覆盖到左边
        /// </summary>
        /// <param name="rowLeft"></param>
        /// <param name="rowRight"></param>
        /// <param name="nvcCompareColNames"></param>
        /// <returns>Is Different</returns>
        public bool CompareDataRowByColsAndOverWriteByRightData(DataRow rowLeft, DataRow rowRight,
                                                                NameValueCollection nvcCompareColNames)
        {
            int diffAmount = 0;
            for (int i = 0; i < nvcCompareColNames.Count; i++)
            {
                string leftColName = nvcCompareColNames.GetKey(i);
                string leftColVal = Convert.ToString(rowLeft[leftColName]);
                string rightColVal = Convert.ToString(rowRight[nvcCompareColNames.Get(i)]);
                if (!leftColVal.Equals(rightColVal))
                {
                    rowLeft[leftColName] = rightColVal;
                    diffAmount++;
                }
            }
            return diffAmount > 0;
        }

        public string FindDiffColNamesInTwoRows(DataRow rowLeft, DataRow rowRight,StringCollection notCompareColNames)
        {
            var scDiffColNames = new StringCollection();
            var reVal = new StringBuilder();
            foreach(DataColumn col in rowLeft.Table.Columns)
            {
                if(!notCompareColNames.Contains(col.ColumnName))
                {
                    var strValLeft = Convert.ToString(rowLeft[col.ColumnName]);
                    var strValRight = Convert.ToString(rowRight[col.ColumnName]);
                    if (!strValLeft.Equals(strValRight) && !scDiffColNames.Contains(col.ColumnName))
                    {
                        scDiffColNames.Add(col.ColumnName);
                        if (reVal.Length > 0) reVal.Append(",");
                        reVal.Append(col.ColumnName);
                    }
                }
                
            }
            return reVal.ToString();
        }

        private void AddRowToCompareResultDataTable(DataTable dtResult,DataRow compareRow, string compareDataSource,
            string compareMemo,string strDiffColNames, StringCollection compareKeyColNames , StringCollection notCompareColNames)
        {
            var rowResult = dtResult.NewRow();
            var compareColLen = compareRow.Table.Columns.Count;
            for (var i = 0; i < compareColLen; i++)
                rowResult[i] = compareRow[i];
            rowResult[CN_Compare_DataSource] = compareDataSource;
            rowResult[CN_Compare_Memo] = compareMemo;
            rowResult[CN_Compare_Diff_ColNames] = strDiffColNames;
            rowResult[CN_Compare_KeyColNames] = DataConvertHelper.StringCollectionToString(compareKeyColNames);
            rowResult[CN_Compare_NotCompareColNames] = DataConvertHelper.StringCollectionToString(notCompareColNames);

            dtResult.Rows.Add(rowResult);
        }

        private const string CN_Compare_DataSource = "Compare_DataSource", CN_Compare_KeyColNames = "Compare_KeyColNames", 
            CN_Compare_NotCompareColNames = "Compare_NotCompareColNames",
            CN_Compare_Memo="Compare_Memo",CN_Compare_Diff_ColNames="Compare_DiffColNames",
            CM_Diff = "内容存在差异",CM_Over="多出的记录",CM_Duplicate = "Key键比对出现多条记录";

        public DataTable CompareTableEachRowIsEquals(DataTable dtLeft,string dataSrcLeft,
            DataTable dtRight, string dataSrcRight, StringCollection keyColNames, StringCollection notCompareColNames)
        {
            var dtReslut = dtLeft.Clone();
            var alLeftMatch = new List<DataRow>();
            var alRightMatch = new List<DataRow>();

            dtReslut.Columns.Add(CN_Compare_DataSource, typeof(string));
            dtReslut.Columns.Add(CN_Compare_Memo, typeof(string));
            
            dtReslut.Columns.Add(CN_Compare_Diff_ColNames, typeof(string));
            dtReslut.Columns.Add(CN_Compare_KeyColNames, typeof(string));
            dtReslut.Columns.Add(CN_Compare_NotCompareColNames, typeof(string));

            

            var repeatAmount = 0;
            for (var i = dtLeft.Rows.Count - 1; i > -1;i-- )
            {
                var rowLeft = dtLeft.Rows[i];
                var sbFindKeyCondition = new StringBuilder();
                foreach (var strColName in keyColNames)
                {
                    if (sbFindKeyCondition.Length > 0) sbFindKeyCondition.Append(" And ");
                    sbFindKeyCondition.Append(strColName + "=" + SqlBuilder.GetColValueByDataType(rowLeft, strColName));
                }

                var rsRight = dtRight.Select(sbFindKeyCondition.ToString());


                if (rsRight.Length == 1)
                {
                    var rowRight = rsRight[0];


                    foreach (string str in keyColNames)
                    {
                        if (notCompareColNames == null) notCompareColNames = new StringCollection();
                        if (!notCompareColNames.Contains(str)) notCompareColNames.Add(str);
                    }

                    var strDiffColNames = FindDiffColNamesInTwoRows(rowLeft, rowRight, notCompareColNames);

                    if (strDiffColNames.Length > 0)
                    {
                        AddRowToCompareResultDataTable(dtReslut, rowLeft, dataSrcLeft, CM_Diff, strDiffColNames,keyColNames,notCompareColNames);
                        AddRowToCompareResultDataTable(dtReslut, rowRight, dataSrcRight, CM_Diff, strDiffColNames, keyColNames, notCompareColNames);
                    }

                    alLeftMatch.Add(rowLeft);
                    dtLeft.Rows.Remove(rowLeft);
                    alRightMatch.Add(rowRight);
                    dtRight.Rows.Remove(rowRight);

                    

                }
                else if (rsRight.Length > 1)
                {
                    foreach (DataRow r in rsRight)
                        AddRowToCompareResultDataTable(dtReslut, r, dataSrcRight, CM_Duplicate, null, keyColNames, notCompareColNames);
                }

            }

            if (dtLeft.Rows.Count > 0)
                foreach (DataRow rowLeft in dtLeft.Rows)
                    AddRowToCompareResultDataTable(dtReslut, rowLeft, dataSrcLeft, CM_Over, null, keyColNames, notCompareColNames);
            if (dtRight.Rows.Count > 0)
                foreach (DataRow rowRight in dtRight.Rows)
                    AddRowToCompareResultDataTable(dtReslut, rowRight, dataSrcRight, CM_Over, null, keyColNames, notCompareColNames);

            return dtReslut;
        }
    }
}